package com.ruoyi.system.controller;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.ruoyi.system.domain.vo.OrderDeptExcel;
import com.ruoyi.system.domain.vo.OrderVo;
import com.ruoyi.system.service.impl.OmsOrderServiceImpl;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.OmsOrder;
import com.ruoyi.system.service.IOmsOrderService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 订单Controller
 *
 * @author ruoyi
 * @date 2024-11-29
 */
@RestController
@RequestMapping("/system/order")
public class OmsOrderController extends BaseController
{
    @Autowired
    private IOmsOrderService omsOrderService;

    /**
     * 查询订单列表
     */
    @PreAuthorize("@ss.hasPermi('system:order:list')")
    @GetMapping("/list")
    public TableDataInfo list(OmsOrder omsOrder)
    {
        startPage();
        List<OmsOrder> list = omsOrderService.selectOmsOrderList(omsOrder);
        return getDataTable(list);
    }




    /**
     * 查询订单-商品列表
     */
    @PreAuthorize("@ss.hasPermi('system:order:list')")
    @GetMapping("/getOrderProductList")
    public AjaxResult getOrderProductList(OmsOrder omsOrder)
    {
        List<OrderVo> list = omsOrderService.getOrderProductList(omsOrder);
        return success(list);
    }

    /**
     * 导出订单列表
     */
    @PreAuthorize("@ss.hasPermi('system:order:export')")
    @Log(title = "订单", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, OmsOrder omsOrder)
    {
        List<OmsOrder> list = omsOrderService.selectOmsOrderList(omsOrder);
        ExcelUtil<OmsOrder> util = new ExcelUtil<OmsOrder>(OmsOrder.class);
        util.exportExcel(response, list, "订单数据");
    }

    /**
     * 获取订单详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:order:query')")
    @GetMapping(value = "/{orderId}")
    public AjaxResult getInfo(@PathVariable("orderId") Long orderId)
    {
        return success(omsOrderService.selectOmsOrderByOrderId(orderId));
    }

    /**
     * 新增订单
     */
    @PreAuthorize("@ss.hasPermi('system:order:add')")
    @Log(title = "订单", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody OmsOrder omsOrder)
    {
        return toAjax(omsOrderService.insertOmsOrder(omsOrder));
    }

    /**
     * 新增订单商品
     */
    @PreAuthorize("@ss.hasPermi('system:order:add')")
    @Log(title = "订单", businessType = BusinessType.INSERT)
    @PostMapping(value = "/addOrderProducts")
    public AjaxResult addOrderProducts(@RequestBody OrderVo omsOrder)
    {
        return toAjax(omsOrderService.addOrderProducts(omsOrder));
    }


    @PreAuthorize("@ss.hasPermi('system:order:export')")
    @Log(title = "订单", businessType = BusinessType.EXPORT)
    @PostMapping("/exportOrderExcel")
    public void exportOrderExcel(HttpServletResponse response, OmsOrder omsOrder) throws IOException {
        List<OrderDeptExcel> orderDeptExcels = omsOrderService.selectOmsOrderExportExcel(omsOrder);
        Map<String,List<OrderDeptExcel>> listMap = orderDeptExcels.stream().collect(Collectors.groupingBy(OrderDeptExcel::getDeptName));


        ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();

        final int[] index = {1};

        exportTotalListExcel(excelWriter,"总表", 0,orderDeptExcels);

        listMap.forEach((key,value)->{
            exportListExcel(excelWriter,key, index[0],value);
            index[0]++;
        });
        excelWriter.finish();


    }

    private  TreeMap<String,Integer> sortMap;

    @Log(title = "订单", businessType = BusinessType.EXPORT)
    @PostMapping("/previewOrder")
    public AjaxResult previewOrder(@RequestBody OmsOrder omsOrder) {
        Map<String,List<List<String>>> result = new HashMap<>();
        List<OrderDeptExcel> orderDeptExcels = omsOrderService.selectOmsOrderExportExcel(omsOrder);
        Map<String,List<OrderDeptExcel>> listMap = orderDeptExcels.stream().collect(Collectors.groupingBy(OrderDeptExcel::getDeptName));
        List<List<String>> totalMap = exportTotalListExcel(orderDeptExcels);
        result.put("总表",totalMap);
        final int[] index = {1};
        listMap.forEach((key,value)->{
            result.put(key,exportListExcel(value));
            index[0]++;
        });
        return success(result);
//        List<OrderDeptExcel> orderDeptExcels = omsOrderService.selectOmsOrderExportExcel(omsOrder);
//        Map<String,List<OrderDeptExcel>> map = new HashMap<>();
//        for(int i=0;i<orderDeptExcels.size();i++){
//            List<OrderDeptExcel> list = new ArrayList<>();
//            if(map.containsKey(orderDeptExcels.get(i).getDeptName())){
//                list =  map.get(orderDeptExcels.get(i).getDeptName());
//            }
//            list.add(orderDeptExcels.get(i));
//            map.put(orderDeptExcels.get(i).getDeptName(),list);
//        }
//        return success(map);



    }




    private List<String> initString(int size){
        List<String> s = new ArrayList<>(size);
        for(int i=0;i<size;i++){
            s.add("");
        }
        return s;
    }

    private void exportTotalListExcel(ExcelWriter excelWriter,String name,int index,List<OrderDeptExcel> list){
        List<List<String>> heads = new ArrayList<List<String>>();
        Map<String,Integer> headNameMap = new HashMap<>();
        Map<String, Integer> totalMap = new HashMap<>();
//        TreeMap<String,Integer> sortMap = new TreeMap<>();
        sortMap = new TreeMap<>();
        int h = 3;
        Map<String,List<String>> dateNameMap = new HashMap<>();
        List<List<String>> data = new ArrayList<List<String>>();
        List<String> head0 = new ArrayList<String>();
        head0.add("商品名称");
        List<String> head1 = new ArrayList<String>();
        head1.add("商品价格");
        List<String> head2 = new ArrayList<String>();
        head2.add("总数");
        heads.add(head0);
        heads.add(head1);
        heads.add(head2);

        for(int i = 0;i<list.size();i++){
            if(null!=list.get(i).getProductName()){
                if(!sortMap.containsKey(list.get(i).getProductName())){
                    int s = 0;
                    if(null!=list.get(i).getSort()){
                        s = list.get(i).getSort().intValue();
                    }
                    else if(null!=list.get(i).getProductId()){
                        s = list.get(i).getProductId().intValue();
                    }
                    sortMap.put(list.get(i).getProductName(),s);
                }
                if(!headNameMap.containsKey(list.get(i).getDeptName())){
                    headNameMap.put(list.get(i).getDeptName(),h);
                    h++;
                    List<String> head = new ArrayList<String>();
                    head.add(list.get(i).getDeptName());
                    heads.add(head);
                }
//            else {
//                int t = totalMap.get(list.get(i).getProductName())+list.get(i).getProductNumber();
//                totalMap.put(list.get(i).getProductName(),t);
//            }

                if(!totalMap.containsKey(list.get(i).getProductName())){
                    totalMap.put(list.get(i).getProductName(),list.get(i).getProductNumber());
                }
                else {
                    int t = totalMap.get(list.get(i).getProductName())+list.get(i).getProductNumber();
                    totalMap.put(list.get(i).getProductName(),t);
                }

                if(!dateNameMap.containsKey(list.get(i).getProductName())){
                    List<String> s = new ArrayList<String>();
                    dateNameMap.put(list.get(i).getProductName(), s);
                }
            }


        }



        for(int j = 0;j<list.size();j++){
            if(null!=list.get(j).getProductName()){
                if(dateNameMap.containsKey(list.get(j).getProductName())){
                    List<String> strings = dateNameMap.get(list.get(j).getProductName());
                    if(strings.size()>0){
                        int num = 0;
                        String str = strings.get(headNameMap.get(list.get(j).getDeptName()));
                        if(str == null || str.equals("")){

                        }
                        else{
                            num = Integer.parseInt(str);
                        }
                        num = num+list.get(j).getProductNumber();
                        strings.set(headNameMap.get(list.get(j).getDeptName()),num+"");
//                        strings.set(headNameMap.get(list.get(j).getDeptName()),list.get(j).getProductNumber().toString());
                        dateNameMap.put(list.get(j).getProductName(),strings);
                    }
                    else {
                        strings = initString(list.get(j).getProductName(),headNameMap.size()+3);
                        strings.set(1,list.get(j).getPrice().toString());
                        strings.set(headNameMap.get(list.get(j).getDeptName()),list.get(j).getProductNumber().toString());
                        dateNameMap.put(list.get(j).getProductName(),strings);
                    }
                }
            }



        }

        totalMap.forEach((key,value)->{
            List<String> strings = dateNameMap.get(key);
            strings.set(2,value.toString());
            dateNameMap.put(key,strings);

        });

        //将Map转换成List
        List<Map.Entry<String,Integer>> lists = new ArrayList<Map.Entry<String,Integer>>(sortMap.entrySet());

        // 通过比较器来实现排序
        Collections.sort(lists, new Comparator<Map.Entry<String,Integer>>()
        {
            @Override
            public int compare(Map.Entry<String,Integer> user1, Map.Entry<String,Integer> user2)
            {
                Integer age1 = user1.getValue();
                Integer age2 = user2.getValue();

                //按照用户年龄降序
                return age1.compareTo(age2);
            }
        });

        for(Map.Entry<String,Integer> entry:lists){
            data.add(dateNameMap.get(entry.getKey()));
        }

//        dateNameMap.forEach((key,value)->{
//            data.add(value);
//        });


        WriteSheet studentSheet =  EasyExcel.writerSheet(index, name).head(heads).build();
        excelWriter.write(data,studentSheet);
    }


    private List<List<String>> exportTotalListExcel(List<OrderDeptExcel> list){
        List<List<String>> heads = new ArrayList<List<String>>();
        Map<String,Integer> headNameMap = new HashMap<>();
        Map<String, Integer> totalMap = new HashMap<>();
        int h = 3;
        Map<String,List<String>> dateNameMap = new HashMap<>();
//        TreeMap<String,Integer> sortMap = new TreeMap<>();
        sortMap = new TreeMap<>();
        List<String> head0 = new ArrayList<String>();
        head0.add("商品名称");
        head0.add("商品价格");
        head0.add("总数");
//        heads.add(head0);
        int sort = 1;
        for(int i = 0;i<list.size();i++){
            if(null!=list.get(i).getProductName()){
                if(!sortMap.containsKey(list.get(i).getProductName())){
                    int s = 0;
                    if(null!=list.get(i).getSort()){
                        s = list.get(i).getSort().intValue();
                    }
                    else if(null!=list.get(i).getProductId()){
                        s = list.get(i).getProductId().intValue();
                    }
                    sortMap.put(list.get(i).getProductName(),s);
                    sort++;
                }
                if(!headNameMap.containsKey(list.get(i).getDeptName())){
                    headNameMap.put(list.get(i).getDeptName(),h);
                    h++;
                    head0.add(list.get(i).getDeptName());
                }
//            else {
//                int t = totalMap.get(list.get(i).getProductName())+list.get(i).getProductNumber();
//                totalMap.put(list.get(i).getProductName(),t);
//            }

                if(!totalMap.containsKey(list.get(i).getProductName())){
                    totalMap.put(list.get(i).getProductName(),list.get(i).getProductNumber());
                }
                else {
                    int j = 0;
                    int m = 0;
                    if(null!=list.get(i).getProductName()){
                        j = totalMap.get(list.get(i).getProductName());
                    }
                    if(null!=list.get(i).getProductNumber()){
                        m=list.get(i).getProductNumber();
                    }
                    int t = j+m;
                    totalMap.put(list.get(i).getProductName(),t);
                }

                if(!dateNameMap.containsKey(list.get(i).getProductName())){
                    List<String> s = new ArrayList<String>();
                    dateNameMap.put(list.get(i).getProductName(), s);
                }
            }


        }



        for(int j = 0;j<list.size();j++){
            if(null!=list.get(j).getProductName()){
                if(dateNameMap.containsKey(list.get(j).getProductName())){
                    List<String> strings = dateNameMap.get(list.get(j).getProductName());
                    if(strings.size()>0){

                        int num = 0;
                        String str = strings.get(headNameMap.get(list.get(j).getDeptName()));
                        if(str == null || str.equals("")){

                        }
                        else{
                            num = Integer.parseInt(str);
                        }
                        num = num+list.get(j).getProductNumber();
                        strings.set(headNameMap.get(list.get(j).getDeptName()),num+"");
                        dateNameMap.put(list.get(j).getProductName(),strings);
                    }
                    else {
                        strings = initString(list.get(j).getProductName(),headNameMap.size()+3);
                        strings.set(1,list.get(j).getPrice().toString());
                        strings.set(headNameMap.get(list.get(j).getDeptName()),list.get(j).getProductNumber().toString());
                        dateNameMap.put(list.get(j).getProductName(),strings);
                    }
                }
            }

        }

        heads.add(head0);
        totalMap.forEach((key,value)->{
            List<String> strings = dateNameMap.get(key);
            strings.set(2,value.toString());
            dateNameMap.put(key,strings);

        });

        //将Map转换成List
        List<Map.Entry<String,Integer>> lists = new ArrayList<Map.Entry<String,Integer>>(sortMap.entrySet());

        // 通过比较器来实现排序
        Collections.sort(lists, new Comparator<Map.Entry<String,Integer>>()
        {
            @Override
            public int compare(Map.Entry<String,Integer> user1, Map.Entry<String,Integer> user2)
            {
                Integer age1 = user1.getValue();
                Integer age2 = user2.getValue();

                //按照用户年龄降序
                return age1.compareTo(age2);
            }
        });

        for(Map.Entry<String,Integer> entry:lists){
            heads.add(dateNameMap.get(entry.getKey()));
        }

//        dateNameMap.forEach((key,value)->{
//            linkedList.add(sortMap.get(key),value);
//        });

        heads.forEach(e->{
            System.out.println(e);
        });


        return heads;
    }



    private void exportListExcel(ExcelWriter excelWriter,String name,int index,List<OrderDeptExcel> list){

        List<List<String>> heads = new ArrayList<List<String>>();
        Map<String,Integer> headNameMap = new HashMap<>();
        Map<String, BigDecimal> totalMap = new HashMap<>();
//        TreeMap<String,Integer> sortMap = new TreeMap<>();

        int h = 1;
        Map<String,List<String>> dateNameMap = new HashMap<>();
        List<List<String>> data = new ArrayList<List<String>>();
        List<String> head0 = new ArrayList<String>();
        head0.add("商品名称");
        heads.add(head0);

        for(int i = 0;i<list.size();i++){
            if(null!=list.get(i).getProductName()){
//                if(!sortMap.containsKey(list.get(i).getProductName())){
//                    int s = 0;
//                    if(null!=list.get(i).getSort()){
//                        s = list.get(i).getSort().intValue();
//                    }
//                    else if(null!=list.get(i).getProductId()){
//                        s = list.get(i).getProductId().intValue();
//                    }
//                    sortMap.put(list.get(i).getProductName(),s);
//                }
                if(!headNameMap.containsKey(list.get(i).getNickName())){
                    headNameMap.put(list.get(i).getNickName(),h);
                    totalMap.put(list.get(i).getNickName(),list.get(i).getTotal());
                    h++;
                    List<String> head = new ArrayList<String>();
                    head.add(list.get(i).getNickName());
                    heads.add(head);
                }
                else {
                    totalMap.put(list.get(i).getNickName(),totalMap.get(list.get(i).getNickName()).add(list.get(i).getTotal()));
                }

                if(!dateNameMap.containsKey(list.get(i).getProductName())){
                    List<String> s = new ArrayList<String>();
                    dateNameMap.put(list.get(i).getProductName(), s);
                }
            }


        }



        for(int j = 0;j<list.size();j++){
            if(null!=list.get(j).getProductName()){
                if(dateNameMap.containsKey(list.get(j).getProductName())){
                    List<String> strings = dateNameMap.get(list.get(j).getProductName());
                    if(strings.size()>0){
                        strings.set(headNameMap.get(list.get(j).getNickName()),list.get(j).getProductNumber().toString());
                        dateNameMap.put(list.get(j).getProductName(),strings);
                    }
                    else {
                        strings = initString(list.get(j).getProductName(),headNameMap.size()+1);
                        strings.set(headNameMap.get(list.get(j).getNickName()),list.get(j).getProductNumber().toString());
                        dateNameMap.put(list.get(j).getProductName(),strings);
                    }
                }
            }



        }

        //将Map转换成List
        List<Map.Entry<String,Integer>> lists = new ArrayList<Map.Entry<String,Integer>>(sortMap.entrySet());

        // 通过比较器来实现排序
        Collections.sort(lists, new Comparator<Map.Entry<String,Integer>>()
        {
            @Override
            public int compare(Map.Entry<String,Integer> user1, Map.Entry<String,Integer> user2)
            {
                Integer age1 = user1.getValue();
                Integer age2 = user2.getValue();

                //按照用户年龄降序
                return age1.compareTo(age2);
            }
        });

        for(Map.Entry<String,Integer> entry:lists){
            if(dateNameMap.containsKey(entry.getKey())){
                data.add(dateNameMap.get(entry.getKey()));
            }
            else {
                List<String> strings = initString("",dateNameMap.size()+1);
                strings.set(0,entry.getKey());
                data.add(strings);
            }
        }
//        dateNameMap.forEach((key,value)->{
//            data.add(value);
//        });

        List<String> totalList = initString("",headNameMap.size()+1);

        totalMap.forEach((key,value)->{
            totalList.set(headNameMap.get(key),value.toString());
//            System.out.println(headNameMap.get(key)+value.toString());

        });
        data.add(totalList);

        WriteSheet studentSheet =  EasyExcel.writerSheet(index, name).head(heads).build();
        excelWriter.write(data,studentSheet);
    }


    private List<List<String>> exportListExcel(List<OrderDeptExcel> list){

        List<List<String>> heads = new ArrayList<>();
        Map<String,Integer> headNameMap = new HashMap<>();
        Map<String, BigDecimal> totalMap = new HashMap<>();
//        TreeMap<String,Integer> sortMap = new TreeMap<>();
        int h = 1;
        Map<String,List<String>> dateNameMap = new HashMap<>();
        List<List<String>> data = new ArrayList<List<String>>();
        List<String> head0 = new ArrayList<String>();
        head0.add("商品名称");

        for(int i = 0;i<list.size();i++){
            if(null!=list.get(i).getProductName()){
//                if(!sortMap.containsKey(list.get(i).getProductName())){
//                    int s = 0;
//                    if(null!=list.get(i).getSort()){
//                        s = list.get(i).getSort().intValue();
//                    }
//                    else if(null!=list.get(i).getProductId()){
//                        s = list.get(i).getProductId().intValue();
//                    }
//                    sortMap.put(list.get(i).getProductName(),s);
//                }
                if(!headNameMap.containsKey(list.get(i).getNickName())){
                    headNameMap.put(list.get(i).getNickName(),h);
                    totalMap.put(list.get(i).getNickName(),list.get(i).getTotal());
                    h++;
                    head0.add(list.get(i).getNickName());
                }
                else {
                    totalMap.put(list.get(i).getNickName(),totalMap.get(list.get(i).getNickName()).add(list.get(i).getTotal()));
                }

                if(!dateNameMap.containsKey(list.get(i).getProductName())){
                    List<String> s = new ArrayList<String>();
                    dateNameMap.put(list.get(i).getProductName(), s);
                }
            }


        }



        for(int j = 0;j<list.size();j++){
            if(null!=list.get(j).getProductName()){
                if(dateNameMap.containsKey(list.get(j).getProductName())){
                    List<String> strings = dateNameMap.get(list.get(j).getProductName());
                    if(strings.size()>0){
                        String s = strings.get(headNameMap.get(list.get(j).getNickName()));
                        if(s!=null && s.length()>0){
                            Integer num = list.get(j).getProductNumber() + Integer.valueOf(s);
                            strings.set(headNameMap.get(list.get(j).getNickName()),num.toString());

                        }
                        else {
                            strings.set(headNameMap.get(list.get(j).getNickName()),list.get(j).getProductNumber().toString());

                        }
//                        System.out.println(s+list.get(j).getProductName());
                        dateNameMap.put(list.get(j).getProductName(),strings);
                    }
                    else {
                        strings = initString(list.get(j).getProductName(),headNameMap.size()+1);
                        strings.set(headNameMap.get(list.get(j).getNickName()),list.get(j).getProductNumber().toString());
                        dateNameMap.put(list.get(j).getProductName(),strings);
                    }
                }
            }



        }
        heads.add(head0);

        List<Map.Entry<String,Integer>> lists = new ArrayList<Map.Entry<String,Integer>>(sortMap.entrySet());

        // 通过比较器来实现排序
        Collections.sort(lists, new Comparator<Map.Entry<String,Integer>>()
        {
            @Override
            public int compare(Map.Entry<String,Integer> user1, Map.Entry<String,Integer> user2)
            {
                Integer age1 = user1.getValue();
                Integer age2 = user2.getValue();

                return age1.compareTo(age2);
            }
        });

        for(Map.Entry<String,Integer> entry:lists){
            if(dateNameMap.containsKey(entry.getKey())){
                heads.add(dateNameMap.get(entry.getKey()));
            }
           else {
               List<String> strings = initString("",headNameMap.size()+1);
               strings.set(0,entry.getKey());
               heads.add(strings);
            }
        }
//        dateNameMap.forEach((key,value)->{
//            heads.add(value);
//        });

        List<String> totalList = initString("",headNameMap.size()+1);

        totalMap.forEach((key,value)->{
            totalList.set(headNameMap.get(key),value.toString());
//            System.out.println(headNameMap.get(key)+value.toString());

        });
        heads.add(totalList);
        Map<String,List<List<String>>> map = new HashMap<>();
        map.put("head",heads);
        map.put("data",data);
        return heads;

    }



    private List<String> initString(String first,int size){
        List<String> s = new ArrayList<>(size);
        for(int i=0;i<size;i++){
            if(i==0){
                s.add(first);
            }
            else {
                s.add("");
            }

        }
        return s;
    }


    /**
     * 修改订单
     */
    @PreAuthorize("@ss.hasPermi('system:order:edit')")
    @Log(title = "订单", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody OmsOrder omsOrder)
    {
        return toAjax(omsOrderService.updateOmsOrder(omsOrder));
    }

    /**
     * 修改订单-商品
     */
    @PreAuthorize("@ss.hasPermi('system:order:edit')")
    @Log(title = "订单", businessType = BusinessType.UPDATE)
    @PutMapping(value = "/updateOrderProducts")
    public AjaxResult updateOrderProducts(@RequestBody OrderVo omsOrder)
    {
        return toAjax(omsOrderService.updateOrderProducts(omsOrder));
    }

    /**
     * 删除订单
     */
    @PreAuthorize("@ss.hasPermi('system:order:remove')")
    @Log(title = "订单", businessType = BusinessType.DELETE)
	@DeleteMapping("/{orderIds}")
    public AjaxResult remove(@PathVariable Long[] orderIds)
    {
        return toAjax(omsOrderService.deleteOmsOrderByOrderIds(orderIds));
    }
}
